/*
 * Copyright 2007-2008  Lukasz Laszko lukaszlaszko@gmail.com
 * 
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for any purpose and without fee is hereby
 * granted, provided that the above copyright notice appear in all
 * copies and that both that the copyright notice and this
 * permission notice and warranty disclaimer appear in supporting
 * documentation, and that the name of the author not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * 
 * The author disclaim all warranties with regard to this
 * software, including all implied warranties of merchantability
 * and fitness.  In no event shall the author be liable for any
 * special, indirect or consequential damages or any damages
 * whatsoever resulting from loss of use, data or profits, whether
 * in an action of contract, negligence or other tortious action,
 * arising out of or in connection with the use or performance of
 * this software. 
 */
package org.pg.biomedics.asr.concurrent;

import edu.cmu.sphinx.util.props.PropertyException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import edu.cmu.sphinx.frontend.FrontEnd;
import edu.cmu.sphinx.frontend.util.StreamDataSource;
import edu.cmu.sphinx.recognizer.Recognizer;
import edu.cmu.sphinx.recognizer.RecognizerState;
import edu.cmu.sphinx.util.props.ConfigurationManager;

import org.pg.biomedics.asr.mbeans.MBeanBuilder;
import org.pg.biomedics.asr.mbeans.VoiceEngineInfo;
import org.pg.biomedics.asr.mbeans.MBeanException;

/**
 * Voice engine instance pooled in object pool
 * @author Lukasz Laszko
 */
public class VoiceEngine 
{
    // <editor-fold desc="Fields">
    
    private ConfigurationManager configurationManager;
    private Recognizer recognizer;
    private StreamDataSource reader;
    private FrontEnd frontEnd;    
    
    // <editor-fold>
    
    // <editor-fold desc="Constructors">
    
    VoiceEngine(String voiceEngineConfig) throws MalformedURLException, IOException, PropertyException
    {
        URL url = new File(voiceEngineConfig).toURI().toURL();
        this.configurationManager = new ConfigurationManager(url);
    }
    
    // </editor-fold>
    
    // <editor-fold desc="Properties">
    
    /**
     * Gets recognizer associated with this ASR engine instance
     * @return recognizer instance
     */
    public Recognizer getRecognizer()
    {
        return recognizer;
    }

    /**
     * Gets input audio stream reader associated to current ASR engine instance
     * @return reader instance
     */
    public StreamDataSource getReader()
    {
        return reader;
    }

    /**
     * Gets ASR engine frontend
     * @return
     */
    public FrontEnd getFrontEnd()
    {
        return frontEnd;
    }
    
    /**
     * Checks if voice engine instance is ininitlized and ready to use
     * @return true- if allocated
     */
    public boolean isReady()
    {
        if (this.reader == null)
            return false;
        
        return ((this.recognizer.getState() != RecognizerState.DEALLOCATED) &&
                (this.recognizer.getState() != RecognizerState.DEALLOCATING) &&
                (this.recognizer.getState() != RecognizerState.ERROR));
    }
    
    // </editor-fold>
    
    // <editor-fold desc="Methods">
    
    /**
     * Allocates voice recognition engie resources
     * @throws java.lang.InstantiationException
     * @throws edu.cmu.sphinx.util.props.PropertyException
     * @throws java.lang.IllegalStateException
     * @throws java.io.IOException
     */
    public void initialize() throws InstantiationException, 
                                    PropertyException, 
                                    IllegalStateException, 
                                    IOException
    {
        if (this.getRecognizer() != null)
            return;
            
        this.recognizer = (Recognizer)this.configurationManager.lookup("wordRecognizer");
        this.reader = (StreamDataSource)this.configurationManager.lookup("streamDataSource");  
        this.frontEnd = (FrontEnd)this.configurationManager.lookup("mfcFrontEnd");

        this.getRecognizer().allocate();
    }
    
    /**
     * Deallocates voice recognition engine resources
     */
    public void shutdown()
    {
        if (this.getRecognizer() == null)
            return;
        
        this.getRecognizer().deallocate();
        
        this.recognizer = null;
        this.reader = null;
        this.frontEnd = null;
    }    
    
    // <editor-fold>
}
